/// @tags: DP StatusCompress
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

using std::cin;
using std::cout;

namespace BlueQuantum {

constexpr int MAXN = 20, P = 1e8 + 7;

int n;
int coll[MAXN][MAXN], f[1 << MAXN][MAXN], popcnt[1 << MAXN];

struct Point {
  int x, y;
  inline bool collinear(const Point &lhs, const Point &rhs) const {
    return (lhs.x - x) * (y - rhs.y) == (x - rhs.x) * (lhs.y - y);
  }
} p[MAXN];

inline int inc(int x, int y) {
  x += y;
  return x >= P ? x - P : x;
}

inline int main() {
  cin >> n;
  for (int i = 0; i < n; ++i) cin >> p[i].x >> p[i].y;
  for (int i = 1, ilim = 1 << n; i < ilim; ++i) popcnt[i] = popcnt[i >> 1] + (i & 1);
  int ans = 0;
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < n; ++j) {
      if (i == j) continue;
      for (int k = 0; k < n; ++k) {
        if (k == i || k == j) continue;
        if (((p[k].x - p[i].x) * (p[k].x - p[j].x) < 0 ||
             (p[k].y - p[i].y) * (p[k].y - p[j].y) < 0) &&
            p[k].collinear(p[i], p[j]))
          coll[i][j] |= (1 << k);
      }
    }
  for (int i = 0; i < n; ++i) f[1 << i][i] = 1;
  for (int i = 1, ilim = 1 << n; i < ilim; ++i) {
    for (int j = 0; j < n; ++j)
      if (f[i][j] && ((i >> j) & 1)) {
        if (popcnt[i] >= 4) ans = inc(ans, f[i][j]);
        for (int k = 0; k < n; ++k)
          if (!((i >> k) & 1) && (coll[j][k] | i) == i) {
            f[i | (1 << k)][k] = inc(f[i | (1 << k)][k], f[i][j]);
          }
      }
  }
  cout << ans;
  return 0;
}

}  // namespace BlueQuantum

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("P4460 [CQOI2018] 解锁屏幕.in", "r", stdin);
  freopen("P4460 [CQOI2018] 解锁屏幕.out", "w", stdout);
#endif
#endif

  std::ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
  return BlueQuantum::main();
}
